//              this is kpDemo's cpp file
//              author: Michael Lee
//              email: michael.20@qq.com

#include "kpdemo.h"
#include "ui_kpdemo.h"


kpDemo::kpDemo(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::kpDemo)
{
    ui->setupUi(this);
    init();
    connect(ui->bRequestToken,SIGNAL(clicked()),this,SLOT(sendRequestToken()));
    connect(ui->webView,SIGNAL(loadFinished(bool)),this,SLOT(getAuthoriseResult(bool)));
    connect(this,SIGNAL(logInResult(bool)),this,SLOT(sendAccessToken(bool)));
    connect(ui->bGetUsrInfo,SIGNAL(clicked()),this,SLOT(reqUsrInfo()));
    connect(ui->bGetMetaData,SIGNAL(clicked()),this,SLOT(reqMetaData()));
    connect(ui->bCreateFolder,SIGNAL(clicked()),this,SLOT(reqCreateFloder()));
    connect(ui->bDelFile,SIGNAL(clicked()),this,SLOT(reqDelFile()));
    connect(ui->bMV,SIGNAL(clicked()),this,SLOT(reqMoveFile()));
    connect(ui->bCP,SIGNAL(clicked()),this,SLOT(reqCopyFile()));
    connect(ui->bUpload,SIGNAL(clicked()),this,SLOT(reqUploadFile()));
    connect(ui->bDownLoad,SIGNAL(clicked()),this,SLOT(reqDownLoadFile()));
    connect(ui->bShare,SIGNAL(clicked()),this,SLOT(reqShareFile()));

    connect(ui->bBrowerUpLocalFile,SIGNAL(clicked()),this,SLOT(openUploadFile()));
    connect(ui->bBroweSaveTo,SIGNAL(clicked()),this,SLOT(saveDwnloadFile()));

}

kpDemo::~kpDemo()
{
    delete ui;
}

//初始化
void kpDemo::init()
{
    manager = new QNetworkAccessManager(this);
    lMsgLabel= new QLabel();
    statusBar()->addWidget(lMsgLabel);
    mReqTokenSecret.clear();
    mReqTokenSecret.append(CONSUMER_SECRET);
    mReqTokenSecret.append("&");
    mAuUrlChangeNum=0;
    mAuthoriseOk=false;
    mIsAppPath=true;
    ui->swUi->setCurrentIndex(SW_KUAIPAN_UI);
    ui->barQuota->setFormat("");
    ui->barDownFile->setValue(0);
    ui->barUpFile->setValue(0);
    ui->barQuota->setValue(0);
    judgeCfgFile();
    ui->tabWidget->setTabText(TAB_GET_META,tr("获取文件(夹)信息"));
    ui->tabWidget->setTabText(TAB_SHARE,tr("获取文件(夹)分享链接"));
    ui->tabWidget->setTabText(TAB_CREATE_NEW,tr("创建文件夹"));
    ui->tabWidget->setTabText(TAB_DEL,tr("删除文件(夹)"));
    ui->tabWidget->setTabText(TAB_MOVE_CPOY,tr("移动/复制文件(夹)"));
    ui->tabWidget->setTabText(TAB_UPLOAD,tr("上传文件"));
    ui->tabWidget->setTabText(TAB_DWNLOAD,tr("下载文件"));
    ui->gbUsrInfo->setTitle(tr("用户信息"));
    ui->bGetUsrInfo->setText(tr("刷新用户信息"));
    ui->lUsrName->setScaledContents(true);
    ui->lUsrName->setGeometry(18,140,171,21);
    this->setMaximumSize(880,539);
    this->setMinimumSize(880,539);
    mUploadNode="NULL";
}

/*
[OAuthInfo]
oauth_token=123456
oauth_token_secret=1988%20abcd
user_id=456
charged_dir=123
*/
//读入配置文件
void kpDemo::judgeCfgFile()
{
    QString path=QCoreApplication::applicationDirPath().append("/cfg.ini");
    cfgFile.setFileName(path);
    if(cfgFile.exists())
    {
        QSettings *cfgReader = new QSettings(cfgFile.fileName(), QSettings::IniFormat);
        cfgReader->setIniCodec("UTF-8");
        mAuTokenInfo.auToken= cfgReader->value("OAuthInfo/oauth_token",QString("NULL")).toString();
        mAuTokenInfo.auTokenSecret=cfgReader->value("OAuthInfo/oauth_token_secret",\
                                                      QString("NULL")).toString();
        mAuTokenInfo.usrID=cfgReader->value("OAuthInfo/user_id",QString("NULL")).toString();
        mAuTokenInfo.usrDirID=cfgReader->value("OAuthInfo/charged_dir",QString("NULL")).toString();

        mUsrInfoStru.usrName=cfgReader->value("OAuthInfo/usrName",QString("NULL")).toString();
        mUploadNode=cfgReader->value("OAuthInfo/UploadNode",QString("NULL")).toString();
        if(mUsrInfoStru.usrName!="NULL")
        {
            ui->lUsrName->setText(mUsrInfoStru.usrName);
        }
        statusBar()->showMessage("已有配置文件!",3000);
    }
}

//添加常用参数
void kpDemo::addTknNonceTimes(QString &paraStr, QString &consKeyStr)
{
    paraStr.append(OACONSUMER_KEY); //cosumer_key
    paraStr.append(consKeyStr);
    paraStr.append("&");
    paraStr.append(OANONCE);        //oauth_nonce
    paraStr.append(getRandNonce());
    paraStr.append("&");
    paraStr.append(OATIMESTAMP);    //oauth_timestamp
    paraStr.append(getTimeStamp());
}

//http错误状态处理
void kpDemo::showErrInfo(int ret,QByteArray &retErrInfo)
{
    QString errInfo=QString(tr("返回错误代码：%1 %2").arg(QString::number(ret))\
                            .arg(QString(retErrInfo)));
    statusBar()->showMessage(errInfo,10000);
}

//打开文件
int kpDemo::openFile(QByteArray &buf,const QString &filePath)
{
    QFile file(filePath);
    if(file.open(QIODevice::ReadOnly))
    {
        buf=file.readAll();
    }
    file.close();
    return buf.size();
}

//--------------------------------------requestToken处理
//
//
//发送requestToken请求
void kpDemo::sendRequestToken()
{
    QString ConsumerKey=QString(CONSUMER_KEY);
    QString ConsumerSecret=QString(CONSUMER_SECRET);
    QString reqTokenUrl=buildReqTknUrl(ConsumerKey,ConsumerSecret);
    inputUrl.setEncodedUrl(reqTokenUrl.toAscii());
    request.setUrl(inputUrl);
    mReqTknReply = manager->get(request);
    connect(mReqTknReply, SIGNAL(finished()),this,SLOT(reqTknReplyFinished()));
}

//构建 reqToken url
QString kpDemo::buildReqTknUrl(QString &consKeyStr, QString &consKeySecretStr)
{
    QString para;
    QString _reqTokenUrl=REQUEST_TOKEN_SRC_URL;
    _reqTokenUrl.append("?");
    _reqTokenUrl.append(OASIGNATURE);
    _reqTokenUrl.append(getReqTknSignature(para,consKeyStr,consKeySecretStr));//添加签名
    _reqTokenUrl.append("&");
    _reqTokenUrl.append(removeUrlEncode(para));//添加去掉编码的参数
    return _reqTokenUrl;
}

//构造reqToken 获取签名
//  oauth_consumer_key
//  oauth_nonce
//  oauth_timestamp
QString kpDemo::getReqTknSignature(QString &paraStr, QString &consKeyStr, QString &consKeySecretStr)
{
    QString ReqTokenBaseUrl;
    ReqTokenBaseUrl.clear(); //将请求的URI路径进行URL编码
    ReqTokenBaseUrl.append("GET&");
    ReqTokenBaseUrl.append(QUrl::toPercentEncoding(REQUEST_TOKEN_SRC_URL));
    ReqTokenBaseUrl.append("&");

    //对参数进行升序排列 然后合并
    addTknNonceTimes(paraStr,consKeyStr);
    ReqTokenBaseUrl.append(QUrl::toPercentEncoding(paraStr));// 对参数进行编码 然后合并成源串
    return  hmacSha1(consKeySecretStr.append("&").toAscii(),ReqTokenBaseUrl.toAscii()); //返回签名
}

//收到临时oauth_token和secret反馈完成
void kpDemo::reqTknReplyFinished()
{
    int ret=mReqTknReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QByteArray getBuf=mReqTknReply->readAll();

    if(CORRECT_RESULT==ret)//返回正确
    {
        procTmpToken(mTmpToken,mTmpTokenSecret,getBuf);//提取mTmpTokenSecret mTmpToken
        setAuthorise(mTmpToken);//进行鉴权
    }
    else
    {
        showErrInfo(ret,getBuf);
    }
    mReqTknReply->deleteLater();
}

//提取临时token和secret
void kpDemo::procTmpToken(QString &tmpToken,QString &tmpTokenSecret, const QByteArray &buf)
{
    //      {"oauth_token_secret": "b0a342c868a84efda1b9fbf937c30b17",
    //        "oauth_token": "88f16ee017514e10a8c6d4a632750c9e",
    //        "oauth_callback_confirmed": false}

    QList<QByteArray> list=buf.simplified().split('"');
    tmpTokenSecret=list.at(TMP_TOKEN_SECRET_INDEX);
    tmpToken=list.at(TMP_TOKEN_INDEX);
}

//--------------------------------------------授权
//用户验证token 登陆授权
void kpDemo::setAuthorise(const QString &tmpToken)
{//https://www.kuaipan.cn/api.php?ac=open&op=authorise&oauth_token=<YourTemporaryToken>
    QString authorizeUrl;
    authorizeUrl.append(AUTHORISE_SRC_URL);
    authorizeUrl.append(tmpToken);
    inputUrl.setUrl(authorizeUrl);
    request.setUrl(inputUrl);
    mAuUrlChangeNum=0;
    mAuthoriseOk=false;
    ui->webView->load(request);
    ui->swUi->setCurrentIndex(SW_WEBVIEW_UI);
}

//判断授权结果
void kpDemo::getAuthoriseResult(bool isFinished)
{
    if(isFinished)
    {
        mAuUrlChangeNum++;
        if(2==mAuUrlChangeNum)
        {
            if(ui->webView->findText("ERROR_OAUTH_TOKEN"))
            {
                mAuthoriseOk=false;
            }
            else
            {
                mAuthoriseOk=true;
                ui->swUi->setCurrentIndex(SW_KUAIPAN_UI);
            }
            emit logInResult(mAuthoriseOk);
        }
    }
}

//-----------------------------------------------AccessToken
//开始AccessToken
void kpDemo::sendAccessToken(bool logInRet)
{
    if(logInRet)//用户已授权
    {
        QString ConsumerKey=QString(CONSUMER_KEY);
        QString ConsumerSecret=QString(CONSUMER_SECRET);
        QString acesTknUrl=buildAcesTknUrl(ConsumerKey,ConsumerSecret,\
                                           mTmpToken,mTmpTokenSecret);
        inputUrl.setEncodedUrl(acesTknUrl.toAscii());
        request.setUrl(inputUrl);
        mAcesTknReply=manager->get(request);
        connect(mAcesTknReply, SIGNAL(finished()),this,SLOT(acesTknReplyFinished()));
    }
    else
    {
        statusBar()->showMessage(tr("用户未授权!"),5000);
    }
}

//构造accessToken url
QString kpDemo::buildAcesTknUrl(QString &consKeyStr, QString &consKeySecretStr, \
                                QString &tmpTknStr, QString &tmpTknSercetStr)
{
    QString para;
    QString _acesTknUrl=ACCESS_TOKEN_SRC_URL;
    _acesTknUrl.append("?");
    _acesTknUrl.append(OASIGNATURE);
    _acesTknUrl.append(getAcesTknSignature(para,consKeyStr,consKeySecretStr,\
                                           tmpTknStr,tmpTknSercetStr));
    //添加签名
    _acesTknUrl.append("&");
    _acesTknUrl.append(removeUrlEncode(para));//添加去掉编码的参数
    return _acesTknUrl;
}

//构造accessToken的签名
//oauth_consumer_key
//oauth_nonce
//oauth_timestamp
//oauth_token
QString kpDemo::getAcesTknSignature(QString &paraStr,\
                                    QString &consKeyStr, QString &consKeySecretStr, \
                                    QString &tmpTknStr, QString &tmpTknSercetStr)
{
    QString acesTknBaseUrl;
    acesTknBaseUrl.clear(); //将请求的URI路径进行URL编码
    acesTknBaseUrl.append("GET&");
    acesTknBaseUrl.append(QUrl::toPercentEncoding(ACCESS_TOKEN_SRC_URL));
    acesTknBaseUrl.append("&");

    //对参数进行升序排列 然后合并
    addTknNonceTimes(paraStr,consKeyStr);
    paraStr.append("&");
    paraStr.append(OATOKEN);
    paraStr.append(tmpTknStr);

    acesTknBaseUrl.append(QUrl::toPercentEncoding(paraStr));// 对参数进行编码 然后合并成源串
    QString secret=consKeySecretStr.append("&");
    secret=secret.append(tmpTknSercetStr);
    return  hmacSha1(secret.toAscii(),acesTknBaseUrl.toAscii()); //返回签名
}

//acessToken包返回完成
void kpDemo::acesTknReplyFinished()
{
    int ret=mAcesTknReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QByteArray getBuf=mAcesTknReply->readAll();
    if(CORRECT_RESULT==ret)//返回正确
    {
        procAuToken(mAuTokenInfo,getBuf);
    }
    else
    {
        showErrInfo(ret,getBuf);
    }
    mAcesTknReply->deleteLater();
}

//提取oauth_token oauth_token_secret charged_dir
void kpDemo::procAuToken(struAuToken &struTkn,const QByteArray &buf)
{
   QList<QByteArray> list=buf.simplified().split('"');
   struTkn.auTokenSecret=list.at(AUTHOR_TOKEN_SECRET_INDEX);
   struTkn.auToken=list.at(AUTHOR_TOKEM_INDEX);
   struTkn.usrDirID=list.at(AUTHOR_USR_DIR);
   QString tmpUsrId=list.at(AUTHOR_USR_ID).trimmed();
   struTkn.usrID=tmpUsrId.mid(2,tmpUsrId.length()-3);

   //写入配置文件
   writeCfg();
   reqUsrInfo();//get usr info
}

//写入配置文件
void kpDemo::writeCfg()
{
    cfgFile.open(QIODevice::WriteOnly);
    cfgFile.close();
    QSettings *cfgReader = new QSettings(cfgFile.fileName(), QSettings::IniFormat);
    cfgReader->setIniCodec("UTF-8");
    cfgReader->setValue("OAuthInfo/oauth_token",mAuTokenInfo.auToken);
    cfgReader->setValue("OAuthInfo/oauth_token_secret",mAuTokenInfo.auTokenSecret);
    cfgReader->setValue("OAuthInfo/user_id",mAuTokenInfo.usrID);
    cfgReader->setValue("OAuthInfo/charged_dir",mAuTokenInfo.usrDirID);
    cfgReader->setValue("OAuthInfo/usrName","NULL");
    cfgReader->setValue("OAuthInfo/uploadNode","NULL");
}


//---------------------------------------------获取用户信息
//获取用户信息
void kpDemo::reqUsrInfo()
{
    QString ConsumerKey=QString(CONSUMER_KEY);
    QString ConsumerSecret=QString(CONSUMER_SECRET);
    QString usrInfoUrl=buildUsrInfoUrl(ConsumerKey,ConsumerSecret,\
                                       mAuTokenInfo.auToken,mAuTokenInfo.auTokenSecret);
    inputUrl.setEncodedUrl(usrInfoUrl.toAscii());
    request.setUrl(inputUrl);
    mUsrInfoReply=manager->get(request);
    connect(mUsrInfoReply, SIGNAL(finished()),this,SLOT(usrInfoReplyFinished()));

}

//构造获取用户信息 url
QString kpDemo::buildUsrInfoUrl(QString &consKeyStr, QString &consKeySecretStr, \
                                QString &oauTknStr, QString &oauTknSercetStr)
{
    QString para;
    QString _usrInfoUrl=GET_USR_INFO_URL;
    _usrInfoUrl.append("?");
    _usrInfoUrl.append(OASIGNATURE);
    _usrInfoUrl.append(getUsrInfoSignature(para,consKeyStr,consKeySecretStr,\
                                           oauTknStr,oauTknSercetStr));
    //添加签名
    _usrInfoUrl.append("&");
    _usrInfoUrl.append(removeUrlEncode(para));//添加去掉编码的参数
    return _usrInfoUrl;
}

//构造获取用户信息 的签名
//oauth_consumer_key
//oauth_nonce
//oauth_timestamp
//oauth_token
QString kpDemo::getUsrInfoSignature(QString &paraStr, \
                                    QString &consKeyStr, QString &consKeySecretStr,\
                                    QString &oauTknStr, QString &oauTknSercetStr)
{
    QString getUsrInfoBaseUrl;
    getUsrInfoBaseUrl.clear(); //将请求的URI路径进行URL编码
    getUsrInfoBaseUrl.append("GET&");
    getUsrInfoBaseUrl.append(QUrl::toPercentEncoding(GET_USR_INFO_URL));
    getUsrInfoBaseUrl.append("&");

    //对参数进行升序排列 然后合并
    addTknNonceTimes(paraStr,consKeyStr);
    paraStr.append("&");
    paraStr.append(OATOKEN);        //oauth_token
    paraStr.append(oauTknStr);

    getUsrInfoBaseUrl.append(QUrl::toPercentEncoding(paraStr));// 对参数进行编码 然后合并成源串

    QString secret=consKeySecretStr.append("&");//构建密钥
    secret=secret.append(oauTknSercetStr);
    return  hmacSha1(secret.toAscii(),getUsrInfoBaseUrl.toAscii()); //返回签名
}

//用户信息已经全部获取完毕
void kpDemo::usrInfoReplyFinished()
{
    int ret=mUsrInfoReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QByteArray getBuf=mUsrInfoReply->readAll();
    if(CORRECT_RESULT==ret)//返回正确
    {
        procUsrInfo(mUsrInfoStru,getBuf);
        setQuotaBar();//更新容量界面
    }
    else
    {
        showErrInfo(ret,getBuf);
    }
    mUsrInfoReply->deleteLater();
}

//存储用户信息到结构体中
void kpDemo::procUsrInfo(struUsrInfo &usrInfo, const QByteArray &buf)
{
    QList<QByteArray> list=buf.split('"');
    QString tmpStr;//去后面一位空格，然后去2~（len-3）位
    tmpStr=list.at(USR_MAX_FILE_SIZE_INDEX).trimmed();//": 314572800, "
    usrInfo.maxFileSize=tmpStr.mid(2,tmpStr.length()-3);

    tmpStr=list.at(USR_TOTAL_SIZE_INDEX).trimmed();
    usrInfo.quotaTotal=tmpStr.mid(2,tmpStr.length()-3);

    tmpStr=list.at(USR_USED_SIZE_INDEX).trimmed();
    usrInfo.quotaUsed=tmpStr.mid(2,tmpStr.length()-3);
    usrInfo.usrName=list.at(USR_NAME_INDEX);
}

//--------------------------------------------获取到用户信息后

//设置容量百分比界面
void kpDemo::setQuotaBar()
{
    double curVal,maxVal;
    QString totalUsed;
    QSettings *cfgReader = new QSettings(cfgFile.fileName(), QSettings::IniFormat);
    cfgReader->setIniCodec("UTF-8");
    cfgReader->setValue("OAuthInfo/usrName",mUsrInfoStru.usrName);//写入用户名到配置文件

    ui->lUsrName->setText(mUsrInfoStru.usrName);

    curVal=(mUsrInfoStru.quotaUsed.toLongLong()/BYTE_TO_MB_UNIT)/1024.00;

    totalUsed.append(QString::number(curVal,'f',2));
    totalUsed.append("G/");
    maxVal=(mUsrInfoStru.quotaTotal.toLongLong()/BYTE_TO_MB_UNIT)/1024.00;
    totalUsed.append(QString::number(maxVal,'f',2));
    totalUsed.append("G");
    ui->lquotaTotalUsed->setText(totalUsed);
    ui->barQuota->setMaximum(maxVal*100);
    ui->barQuota->setValue(curVal*100);
}

//-------------------------------------------------获取文件夹信息
//获取文件夹信息
void kpDemo::reqMetaData()
{
    ui->plainTextEdit->clear();
    struMetaDataPara dataParaStru;
    dataParaStru.useDataPara=false;
    dataParaStru.page=0;
    dataParaStru.page_size=512;
    dataParaStru.sort_by="size";
    bool isAppPath=true;
    QString ConsumerKey=QString(CONSUMER_KEY);
    QString ConsumerSecret=QString(CONSUMER_SECRET);
    QString dataPath=QUrl::toPercentEncoding(ui->tMetaDataPath->text());
    QString metaDataUrl=buildMetaDataUrl(ConsumerKey,ConsumerSecret,\
                                       mAuTokenInfo.auToken,mAuTokenInfo.auTokenSecret,\
                                         dataParaStru,isAppPath,dataPath);

    inputUrl.setEncodedUrl(metaDataUrl.toAscii());
    request.setUrl(inputUrl);
    mMetaDataReply=manager->get(request);

    //此处用于阻塞式
//    QEventLoop eLoop;
//    connect(mMetaDataReply, SIGNAL(finished()), &eLoop, SLOT(
//    quit()));
//    eLoop.exec();

//    int ret=mMetaDataReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
//    QByteArray getBuf=mMetaDataReply->readAll();
//    if(CORRECT_RESULT==ret)//返回正确
//    {
//        // procUsrInfo(mUsrInfoStru,getBuf);
//        procMetaData(getBuf);
//    }
//    else
//    {
//        showErrInfo(ret,getBuf);
//    }
    connect(mMetaDataReply, SIGNAL(finished()),this,SLOT(metaDataReplyFinished()));
}

//构造获取文件夹信息url
QString kpDemo::buildMetaDataUrl(QString &consKeyStr, QString &consKeySecretStr,\
                                 QString &oauTknStr, QString &oauTknSercetStr,\
                                 struMetaDataPara &dataPara,bool &isAppPath,QString &dataPath)
{
    QString para;
    QString newGetMetaDataUrl(GET_META_DATA_URL);
    if(isAppPath)
    {
        newGetMetaDataUrl.append("app_folder");
    }
    else newGetMetaDataUrl.append("kuaipan");
    if(dataPath.length()>0)
    {
        newGetMetaDataUrl.append("/");
        newGetMetaDataUrl.append(dataPath);
    }
    QString _metaDataUrl=newGetMetaDataUrl;
    _metaDataUrl.append("?");
    _metaDataUrl.append(OASIGNATURE);
    _metaDataUrl.append(getMetaDataSignature(para,consKeyStr,consKeySecretStr,\
                                           oauTknStr,oauTknSercetStr,dataPara,\
                                             newGetMetaDataUrl));

    //添加签名
    _metaDataUrl.append("&");
    _metaDataUrl.append(removeUrlEncode(para));//添加去掉编码的参数
    return _metaDataUrl;
}

//构造获取文件夹信息的签名
//*file_limit
//*filter_ext
//*list
//oauth_consumer_key
//oauth_nonce
//oauth_timestamp
//oauth_token
//page
//page_size
//sort_by
QString kpDemo::getMetaDataSignature(QString &paraStr, \
                                     QString &consKeyStr, QString &consKeySecretStr, \
                                     QString &oauTknStr, QString &oauTknSercetStr,\
                                     struMetaDataPara &dataPara,QString &newGetMetaUrl)
{

    QString getMetaDataBaseUrl;
    getMetaDataBaseUrl.clear(); //将请求的URI路径进行URL编码
    getMetaDataBaseUrl.append("GET&");
    getMetaDataBaseUrl.append(QUrl::toPercentEncoding(newGetMetaUrl));
    getMetaDataBaseUrl.append("&");

    //对参数进行升序排列 然后合并
    addTknNonceTimes(paraStr,consKeyStr);
    paraStr.append("&");
    paraStr.append(OATOKEN);        //oauth_token
    paraStr.append(oauTknStr);

    if(dataPara.useDataPara)
    {
        paraStr.append("&");
        paraStr.append(DATA_PAGE);
        paraStr.append(QString::number(dataPara.page));
        paraStr.append("&");
        paraStr.append(DATA_PAGE_SIZE);
        paraStr.append(QString::number(dataPara.page_size));
        paraStr.append("&");

        paraStr.append(DATA_SORT_BY);
        paraStr.append(dataPara.sort_by);
    }


    getMetaDataBaseUrl.append(QUrl::toPercentEncoding(paraStr));// 对参数进行编码 然后合并成源串

    QString secret=consKeySecretStr.append("&");//构建密钥
    secret=secret.append(oauTknSercetStr);
    return  hmacSha1(secret.toAscii(),getMetaDataBaseUrl.toAscii()); //返回签名
}

//metaData读完
void kpDemo::metaDataReplyFinished()
{
    int ret=mMetaDataReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QByteArray getBuf=mMetaDataReply->readAll();
    if(CORRECT_RESULT==ret)//返回正确
    {
       // procUsrInfo(mUsrInfoStru,getBuf);
        procMetaData(getBuf);
    }
    else
    {
        showErrInfo(ret,getBuf);
    }
    mMetaDataReply->deleteLater();
}

//提取文件夹信息
void kpDemo::procMetaData(const QByteArray &buf)
{
    QString str=QString(buf).remove(' ');
    str=str.remove(',');
    str=str.remove('\n');
    QList<QString> list=str.split('{');

    for(int i=0;i<list.size();i++)
    {
        ui->plainTextEdit->insertPlainText(list.at(i)+"\n");
    }
    qDebug("file num:%d",str.count("name"));
}

//----------------------------------------------新建文件夹
//创建文件夹
void kpDemo::reqCreateFloder()
{
    QString ConsumerKey=QString(CONSUMER_KEY);
    QString ConsumerSecret=QString(CONSUMER_SECRET);
    QString newFolderPath=ui->tCreateFolderName->text();
    QString createFolderUrl=buildCreateFolderUrl(ConsumerKey,ConsumerSecret,\
                                                 mAuTokenInfo.auToken,mAuTokenInfo.auTokenSecret,\
                                                 mIsAppPath,newFolderPath);
    inputUrl.setEncodedUrl(createFolderUrl.toAscii());
    request.setUrl(inputUrl);
    mCreateFolderReply=manager->get(request);
    connect(mCreateFolderReply,SIGNAL(finished()),this,SLOT(createFolderReplyFinished()));

}

//构造创建文件夹rul
QString kpDemo::buildCreateFolderUrl(QString &consKeyStr,QString &consKeySecretStr,\
                                     QString &oauTknStr,QString &oauTknSercetStr,\
                                     bool &isAppPath,QString &folderName)
{
    QString para;
    QString _createFolderUrl=CREATE_FOLDER_URL;
    _createFolderUrl.append("?");
    _createFolderUrl.append(OASIGNATURE);
    _createFolderUrl.append(getCreateFolderSignature(para,consKeyStr,consKeySecretStr,\
                                           oauTknStr,oauTknSercetStr,isAppPath,folderName));

    //添加签名
    _createFolderUrl.append("&");
    _createFolderUrl.append(para);//添加无编码的参数
    return _createFolderUrl;
}

//构造创建文件夹的签名
//oauth_consumer_key
//oauth_nonce
//oauth_timestamp
//oauth_token
//path
//root
QString kpDemo::getCreateFolderSignature(QString &paraStr,QString &consKeyStr, QString &consKeySecretStr,\
                                         QString &oauTknStr, QString &oauTknSercetStr,\
                                         bool &isAppPath,QString &folderName)
{
    QString createFolderBaseUrl;
    createFolderBaseUrl.clear(); //将请求的URI路径进行URL编码
    createFolderBaseUrl.append("GET&");
    createFolderBaseUrl.append(QUrl::toPercentEncoding(CREATE_FOLDER_URL));
    createFolderBaseUrl.append("&");

    //对参数进行升序排列 然后合并
    addTknNonceTimes(paraStr,consKeyStr);
    paraStr.append("&");
    paraStr.append(OATOKEN);        //oauth_token
    paraStr.append(oauTknStr);

    paraStr.append("&");
    paraStr.append(FOLDER_NAME);
    paraStr.append(QString(QUrl::toPercentEncoding(folderName)));
    paraStr.append("&");
    paraStr.append(FOLDER_ROOT);
    if(isAppPath)
    {
        paraStr.append("app_folder");
    }
    else
    {
        paraStr.append("kuaipan");
    }

    createFolderBaseUrl.append(QUrl::toPercentEncoding(paraStr));// 对参数进行编码 然后合并成源串
    QString secret=consKeySecretStr.append("&");//构建密钥
    secret=secret.append(oauTknSercetStr);
    return  hmacSha1(secret.toAscii(),createFolderBaseUrl.toAscii()); //返回签名
}

//创建文件夹 反馈完毕
void kpDemo::createFolderReplyFinished()
{
    int ret=mCreateFolderReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QByteArray getBuf=mCreateFolderReply->readAll();
    if(CORRECT_RESULT==ret)//返回正确
    {
        procCreateFolder(getBuf);
    }
    else
    {
        showErrInfo(ret,getBuf);
    }
    mCreateFolderReply->deleteLater();
}

//提取创建文件夹 反馈结果
void kpDemo::procCreateFolder(const QByteArray &buf)
{
    QList<QByteArray> list=buf.split('"');
    statusBar()->showMessage("create "+list.at(7)+" "+list.at(3),2000);
}

//-------------------------------------------删除文件
//删除文件
void kpDemo::reqDelFile()
{
    bool toRecyle=true;
    QString ConsumerKey=QString(CONSUMER_KEY);
    QString ConsumerSecret=QString(CONSUMER_SECRET);
    QString needToDelFileName=ui->tDelFilePath->text();
    QString delFileUrl=buildDelFileUrl(ConsumerKey,ConsumerSecret,\
                                       mAuTokenInfo.auToken,mAuTokenInfo.auTokenSecret,\
                                       mIsAppPath,needToDelFileName,toRecyle);

    inputUrl.setEncodedUrl(delFileUrl.toAscii());
    request.setUrl(inputUrl);
    mDelFileReply=manager->get(request);
    connect(mDelFileReply,SIGNAL(finished()),this,SLOT(delFileReplyFinished()));
}

//构造删除文件的url
QString kpDemo::buildDelFileUrl(QString &consKeyStr, QString &consKeySecretStr,\
                                QString &oauTknStr, QString &oauTknSercetStr, \
                                bool &isAppPath, QString &fileName, bool &toRecyle)
{
    QString para;
    QString _delFileUrl=DEL_FILE_URL;
    _delFileUrl.append("?");
    _delFileUrl.append(OASIGNATURE);
    _delFileUrl.append(getDelFileSignature(para,consKeyStr,consKeySecretStr,\
                                           oauTknStr,oauTknSercetStr,isAppPath,fileName,toRecyle));

    //添加签名
    _delFileUrl.append("&");
    _delFileUrl.append(para);//添加无编码的参数
    return _delFileUrl;
}

//构造删除文件 的签名
//oauth_consumer_key
//oauth_nonce
//oauth_timestamp
//oauth_token
//path
//root
//to_recycle
QString kpDemo::getDelFileSignature(QString &paraStr,QString &consKeyStr, QString &consKeySecretStr, \
                                    QString &oauTknStr, QString &oauTknSercetStr, \
                                    bool &isAppPath, QString &fileName, bool &toRecyle)
{
    QString delFileBaseUrl;
    delFileBaseUrl.clear(); //将请求的URI路径进行URL编码
    delFileBaseUrl.append("GET&");
    delFileBaseUrl.append(QUrl::toPercentEncoding(DEL_FILE_URL));
    delFileBaseUrl.append("&");

    //对参数进行升序排列 然后合并
    addTknNonceTimes(paraStr,consKeyStr);
    paraStr.append("&");
    paraStr.append(OATOKEN);        //oauth_token
    paraStr.append(oauTknStr);
    paraStr.append("&");
    paraStr.append(FOLDER_NAME);
    paraStr.append(QString(QUrl::toPercentEncoding(fileName)));
    paraStr.append("&");
    paraStr.append(FOLDER_ROOT);
    if(isAppPath)
    {
        paraStr.append("app_folder&");
    }
    else
    {
        paraStr.append("kuaipan&");
    }
    paraStr.append(TO_RECYLE);
    if(toRecyle)
    {
        paraStr.append("True");
    }
    else paraStr.append("False");

    delFileBaseUrl.append(QUrl::toPercentEncoding(paraStr));// 对参数进行编码 然后合并成源串
    QString secret=consKeySecretStr.append("&");//构建密钥
    secret=secret.append(oauTknSercetStr);
    return  hmacSha1(secret.toAscii(),delFileBaseUrl.toAscii()); //返回签名
}

//删除文件反馈全部完毕
void kpDemo::delFileReplyFinished()
{
    int ret=mDelFileReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QByteArray getBuf=mDelFileReply->readAll();
    if(CORRECT_RESULT==ret)//返回正确
    {
        procDelFile(getBuf);
    }
    else
    {
        showErrInfo(ret,getBuf);
    }
    mDelFileReply->deleteLater();
}

//提取删除文件的反馈信息
void kpDemo::procDelFile(const QByteArray &buf)
{
    QList<QByteArray> list=buf.split('"');
    statusBar()->showMessage("del file:"+list.at(3),3000);
}

//-----------------------------------------剪切文件
//请求剪切文件
void kpDemo::reqMoveFile()
{
    QString fromPath=ui->tFromPath->text();
    QString toPath=ui->tToPath->text();
    QString ConsumerKey=QString(CONSUMER_KEY);
    QString ConsumerSecret=QString(CONSUMER_SECRET);
    QString moveFileUrl=buildMoveFileUrl(ConsumerKey,ConsumerSecret,\
                                         mAuTokenInfo.auToken,mAuTokenInfo.auTokenSecret,\
                                         mIsAppPath,fromPath,toPath);
    inputUrl.setEncodedUrl(moveFileUrl.toAscii());
    request.setUrl(inputUrl);
    mMvFileReply=manager->get(request);
    connect(mMvFileReply,SIGNAL(finished()),this,SLOT(moveFileReplyFinished()));

}

//构造剪切文件的url
QString kpDemo::buildMoveFileUrl(QString &consKeyStr, QString &consKeySecretStr,\
                                 QString &oauTknStr, QString &oauTknSercetStr,\
                                 bool &isAppPath, QString &fromPath, QString &toPath)
{
    QString para;
    QString _mvFileUrl=MOVE_FILE_URL;
    _mvFileUrl.append("?");
    _mvFileUrl.append(OASIGNATURE);
    _mvFileUrl.append(getMoveFileSignature(para,consKeyStr,consKeySecretStr,\
                                           oauTknStr,oauTknSercetStr,isAppPath,fromPath,toPath));
    //添加签名
    _mvFileUrl.append("&");
    _mvFileUrl.append(para);//添加无编码的参数
    return _mvFileUrl;
}

//构造剪切文件的签名
//from_path
//oauth_consumer_key
//oauth_nonce
//oauth_timestamp
//oauth_token
//root
//to_path
QString kpDemo::getMoveFileSignature(QString &paraStr,QString &consKeyStr, QString &consKeySecretStr,\
                                     QString &oauTknStr, QString &oauTknSercetStr,\
                                     bool &isAppPath, QString &fromPath, QString &toPath)
{
    QString mvFileBaseUrl;
    mvFileBaseUrl.clear(); //将请求的URI路径进行URL编码
    mvFileBaseUrl.append("GET&");
    mvFileBaseUrl.append(QUrl::toPercentEncoding(MOVE_FILE_URL));
    mvFileBaseUrl.append("&");

    paraStr.append(DATA_FROM_PATH);
    paraStr.append(QUrl::toPercentEncoding(fromPath));
    paraStr.append("&");

    //对参数进行升序排列 然后合并
    addTknNonceTimes(paraStr,consKeyStr);
    paraStr.append("&");
    paraStr.append(OATOKEN);        //oauth_token
    paraStr.append(oauTknStr);

    paraStr.append("&");
    paraStr.append(FOLDER_ROOT);
    if(isAppPath)
    {
        paraStr.append("app_folder&");
    }
    else
    {
        paraStr.append("kuaipan&");
    }
    paraStr.append(DATA_TO_PATH);
    paraStr.append(QUrl::toPercentEncoding(toPath));

    mvFileBaseUrl.append(QUrl::toPercentEncoding(paraStr));// 对参数进行编码 然后合并成源串
    QString secret=consKeySecretStr.append("&");//构建密钥
    secret=secret.append(oauTknSercetStr);
    return  hmacSha1(secret.toAscii(),mvFileBaseUrl.toAscii()); //返回签名
}

//剪切文件后反馈完毕
void kpDemo::moveFileReplyFinished()
{
    int ret=mMvFileReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QByteArray getBuf=mMvFileReply->readAll();
    if(CORRECT_RESULT==ret)//返回正确
    {
        procMvFile(getBuf);
    }
    else
    {
        showErrInfo(ret,getBuf);
    }
    mMvFileReply->deleteLater();
}

//提取剪切文件的反馈信息
void kpDemo::procMvFile(const QByteArray &buf)
{
    QList<QByteArray> list=buf.split('"');
    statusBar()->showMessage("mv file:"+list.at(3),3000);
}

//------------------------------------------复制文件
//请求复制文件
void kpDemo::reqCopyFile()
{
    QString fromPath=ui->tFromPath->text();
    QString toPath=ui->tToPath->text();
    QString ConsumerKey=QString(CONSUMER_KEY);
    QString ConsumerSecret=QString(CONSUMER_SECRET);
    QString copyFileUrl=buildCopyFileUrl(ConsumerKey,ConsumerSecret,\
                                         mAuTokenInfo.auToken,mAuTokenInfo.auTokenSecret,\
                                         mIsAppPath,fromPath,toPath);
    inputUrl.setEncodedUrl(copyFileUrl.toAscii());
    request.setUrl(inputUrl);
    mCpFileReply=manager->get(request);
    connect(mCpFileReply,SIGNAL(finished()),this,SLOT(copyFileReplyFinished()));
}

//构造复制文件的 url
QString kpDemo::buildCopyFileUrl(QString &consKeyStr, QString &consKeySecretStr,\
                                 QString &oauTknStr, QString &oauTknSercetStr,\
                                 bool &isAppPath, QString &fromPath, QString &toPath)
{
    QString para;
    QString _cpFileUrl=COPY_FILE_URL;
    _cpFileUrl.append("?");
    _cpFileUrl.append(OASIGNATURE);
    _cpFileUrl.append(getCopyFileSignature(para,consKeyStr,consKeySecretStr,\
                                           oauTknStr,oauTknSercetStr,isAppPath,fromPath,toPath));
    //添加签名
    _cpFileUrl.append("&");
    _cpFileUrl.append(para);//添加无编码的参数
    return _cpFileUrl;
}

//构造复制文件的 签名
//from_path
//oauth_consumer_key
//oauth_nonce
//oauth_timestamp
//oauth_token
//root
//to_path
QString kpDemo::getCopyFileSignature(QString &paraStr, QString &consKeyStr, QString &consKeySecretStr,\
                                     QString &oauTknStr, QString &oauTknSercetStr, \
                                     bool &isAppPath, QString &fromPath, QString &toPath)
{
    QString cpFileBaseUrl;
    cpFileBaseUrl.clear(); //将请求的URI路径进行URL编码
    cpFileBaseUrl.append("GET&");
    cpFileBaseUrl.append(QUrl::toPercentEncoding(COPY_FILE_URL));
    cpFileBaseUrl.append("&");

    paraStr.append(DATA_FROM_PATH);
    paraStr.append(QUrl::toPercentEncoding(fromPath));
    paraStr.append("&");

    //对参数进行升序排列 然后合并
    addTknNonceTimes(paraStr,consKeyStr);
    paraStr.append("&");
    paraStr.append(OATOKEN);        //oauth_token
    paraStr.append(oauTknStr);

    paraStr.append("&");
    paraStr.append(FOLDER_ROOT);
    if(isAppPath)
    {
        paraStr.append("app_folder&");
    }
    else
    {
        paraStr.append("kuaipan&");
    }
    paraStr.append(DATA_TO_PATH);
    paraStr.append(QUrl::toPercentEncoding(toPath));

    cpFileBaseUrl.append(QUrl::toPercentEncoding(paraStr));// 对参数进行编码 然后合并成源串
    QString secret=consKeySecretStr.append("&");//构建密钥
    secret=secret.append(oauTknSercetStr);
    return  hmacSha1(secret.toAscii(),cpFileBaseUrl.toAscii()); //返回签名
}

//复制文件 反馈结束
void kpDemo::copyFileReplyFinished()
{
    int ret=mCpFileReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QByteArray getBuf=mCpFileReply->readAll();
    if(CORRECT_RESULT==ret)//返回正确
    {
        statusBar()->showMessage(tr("复制成功"),3000);
    }
    else
    {
        showErrInfo(ret,getBuf);
    }
    mCpFileReply->deleteLater();
}

//-----------------------------------------上传文件
//请求上传文件(先获取上传节点)
void kpDemo::reqUploadFile()
{
    ui->barUpFile->setValue(0);
    //获取上传节点
    if("NULL"==mUploadNode)
    {
        QString ConsumerKey=QString(CONSUMER_KEY);
        QString ConsumerSecret=QString(CONSUMER_SECRET);
        QString uploadLocUrl=buildUploadLocateUrl(ConsumerKey,ConsumerSecret,\
                                                  mAuTokenInfo.auToken,mAuTokenInfo.auTokenSecret);
        inputUrl.setEncodedUrl(uploadLocUrl.toAscii());
        request.setUrl(inputUrl);
        mUploadLocateReply=manager->get(request);
        connect(mUploadLocateReply,SIGNAL(finished()),this,SLOT(getUploadLocateFinished()));
    }
    else //已获取上传节点
    {
        QByteArray data;
        QString toPath=ui->tRemoteUploadPath->text();
        QString ConsumerKey=QString(CONSUMER_KEY);
        QString ConsumerSecret=QString(CONSUMER_SECRET);
        bool isOverWrite=true;
        bool isAppPath=true;
        QString uploadFileUrl=buildUploadFileUrl(ConsumerKey,ConsumerSecret,\
                                                 mAuTokenInfo.auToken,mAuTokenInfo.auTokenSecret,\
                                                 isOverWrite,isAppPath,toPath,mUploadNode);

        inputUrl.setEncodedUrl(uploadFileUrl.toAscii());
        uploadRequest.setUrl(inputUrl);
        buildMultiPart(data);//使用multipart方式上传 构造multipart包
        mUploadFileReply=manager->post(uploadRequest,data);//上传
        connect(mUploadFileReply,SIGNAL(finished()),this,SLOT(upLoadFileReplyFinished()));
        connect(mUploadFileReply,SIGNAL(uploadProgress(qint64,qint64)),\
                this,SLOT(showUploadProgress(qint64,qint64)));
    }
}

//构造获取上传接口地址的url
QString kpDemo::buildUploadLocateUrl(QString &consKeyStr, QString &consKeySecretStr,\
                                     QString &oauTknStr, QString &oauTknSercetStr)
{
    QString para;
    QString _locateUrl=UPLOAD_LOCATE_URL;
    _locateUrl.append("?");
    _locateUrl.append(OASIGNATURE);
    _locateUrl.append(getUploadLocateSignature(para,consKeyStr,consKeySecretStr,\
                                           oauTknStr,oauTknSercetStr));
    //添加签名
    _locateUrl.append("&");
    _locateUrl.append(para);//添加无编码的参数
    return _locateUrl;
}

//构造获取上传地址的签名
QString kpDemo::getUploadLocateSignature(QString &paraStr, QString &consKeyStr, QString &consKeySecretStr,\
                                         QString &oauTknStr, QString &oauTknSercetStr)
{
    QString upLocaBaseUrl;
    upLocaBaseUrl.clear(); //将请求的URI路径进行URL编码
    upLocaBaseUrl.append("GET&");
    upLocaBaseUrl.append(QUrl::toPercentEncoding(UPLOAD_LOCATE_URL));
    upLocaBaseUrl.append("&");

    //对参数进行升序排列 然后合并
    addTknNonceTimes(paraStr,consKeyStr);
    paraStr.append("&");
    paraStr.append(OATOKEN);        //oauth_token
    paraStr.append(oauTknStr);

    upLocaBaseUrl.append(QUrl::toPercentEncoding(paraStr));// 对参数进行编码 然后合并成源串
    QString secret=consKeySecretStr.append("&");//构建密钥
    secret=secret.append(oauTknSercetStr);
    return  hmacSha1(secret.toAscii(),upLocaBaseUrl.toAscii()); //返回签名
}

//构建上传文件的url
QString kpDemo::buildUploadFileUrl(QString &consKeyStr, QString &consKeySecretStr,\
                                   QString &oauTknStr, QString &oauTknSercetStr,\
                                   const bool &isOverWrite, const bool &isAppPath, \
                                   const QString &toPath, QString &preStr)
{
    QString para;
    QString fullUploadFileUrl=preStr.append(UPLOAD_FILE_URL);
    QString _sendFileUrl=fullUploadFileUrl;
    _sendFileUrl.append("?");
    _sendFileUrl.append(OASIGNATURE);
    _sendFileUrl.append(getUploadFileSignature(para,consKeyStr,consKeySecretStr,\
                                                 oauTknStr,oauTknSercetStr,\
                                               isOverWrite,isAppPath,\
                                               toPath,fullUploadFileUrl));
    //添加签名
    _sendFileUrl.append("&");
    _sendFileUrl.append(para);//添加无编码的参数
    return _sendFileUrl;
}

//构建上传文件的 签名
//oauth_consumer_key
//oauth_nonce
//oauth_timestamp
//oauth_token
//overwrite
//path
//root
QString kpDemo::getUploadFileSignature(QString &paraStr, QString &consKeyStr, QString &consKeySecretStr,\
                                       QString &oauTknStr, QString &oauTknSercetStr,\
                                       const bool &isOverWrite, const bool &isAppPath, \
                                       const QString &toPath,QString &fullUrl)
{
    QString uploadFileBaseUrl;
    uploadFileBaseUrl.clear(); //将请求的URI路径进行URL编码
    uploadFileBaseUrl.append("POST&");
    uploadFileBaseUrl.append(QUrl::toPercentEncoding(fullUrl));
    uploadFileBaseUrl.append("&");


    //对参数进行升序排列 然后合并
    addTknNonceTimes(paraStr,consKeyStr);
    paraStr.append("&");
    paraStr.append(OATOKEN);        //oauth_token
    paraStr.append(oauTknStr);

    paraStr.append("&");
    paraStr.append(UPLOAD_OVER_WRITE); //overwrite
    if(isOverWrite)
        paraStr.append("True");
    else paraStr.append("False");

    paraStr.append("&");
    paraStr.append(FOLDER_NAME);       //path
    paraStr.append(QUrl::toPercentEncoding(toPath));
    paraStr.append("&");
    paraStr.append(FOLDER_ROOT);        //root
    if(isAppPath)
    {
        paraStr.append("app_folder");
    }
    else
    {
        paraStr.append("kuaipan");
    }

    uploadFileBaseUrl.append(QUrl::toPercentEncoding(paraStr));// 对参数进行编码 然后合并成源串
    QString secret=consKeySecretStr.append("&");//构建密钥
    secret=secret.append(oauTknSercetStr);
    return  hmacSha1(secret.toAscii(),uploadFileBaseUrl.toAscii()); //返回签名
}

//获取到上传节点
void kpDemo::getUploadLocateFinished()
{
    int ret=mUploadLocateReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QByteArray getBuf=mUploadLocateReply->readAll();
    mUploadLocateReply->deleteLater();
    if(CORRECT_RESULT==ret)
    {
        QList<QByteArray> list=getBuf.split('"');

        mUploadNode=list.at(3);//上传节点
        QSettings *cfgReader = new QSettings(cfgFile.fileName(), QSettings::IniFormat);
        cfgReader->setIniCodec("UTF-8");
        cfgReader->setValue("OAuthInfo/uploadNode",mUploadNode);//写入上传节点到配置文件
        reqUploadFile();
    }
    else
    {
        showErrInfo(ret,getBuf);
    }
}

//上传文件 反馈完毕
void kpDemo::upLoadFileReplyFinished()
{
    int ret=mUploadFileReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QByteArray getBuf=mUploadFileReply->readAll();
    if(CORRECT_RESULT==ret)//返回正确
    {
        statusBar()->showMessage(tr("上传成功!"),2000);
    }
    else
    {
        showErrInfo(ret,getBuf);
    }
    mUploadFileReply->deleteLater();
}

//上传进度条
void kpDemo::showUploadProgress(qint64 bytesWrite, qint64 totalBytes)
{
    ui->barUpFile->setMaximum(totalBytes);
    ui->barUpFile->setValue(bytesWrite);
}

//构造multipart
void kpDemo::buildMultiPart(QByteArray &data)
{
    QByteArray needToUploadFile;
    QString localPath=ui->tLocalUploadPath->text();
    if(openFile(needToUploadFile,localPath)<=0)
    {
        QMessageBox::warning(this,tr("错误"),tr("无法打开文件")+localPath);
        return ;
    }

    QString crlf="\r\n";
    QString boundary="--------Michael"+getRandNonce();
    QString contentType="multipart/form-data; boundary="+boundary; //开始的头部信息

    QString endBoundary=crlf+"--"+boundary+"--"+crlf; //结束处

    boundary="--"+boundary+crlf; //每行数据开头
    QByteArray bond=boundary.toAscii();

    data.append(bond);


    data.append(QString("Content-Disposition: form-data; name=\"file\"; filename=\""\
                        +localPath+"\""+crlf).toAscii());
    data.append(QString("Content-Type: application/octet-stream"+crlf).toAscii());
    data.append(crlf.toAscii());
    data.append(needToUploadFile);
    data.append(endBoundary.toAscii());
    uploadRequest.setHeader(QNetworkRequest::ContentTypeHeader, contentType.toAscii());
    uploadRequest.setHeader(QNetworkRequest::ContentLengthHeader, QVariant(data.size()).toString());
}

//----------------------------------------下载文件
//请求下载文件
void kpDemo::reqDownLoadFile()
{
    mDwnFileBuf.clear();
    bool isAppPath=true;
    QString ConsumerKey=QString(CONSUMER_KEY);
    QString ConsumerSecret=QString(CONSUMER_SECRET);
    QString fromPath=ui->tRemoteDwnPath->text();
    dwnFile=new QFile(ui->tLocalDwnPath->text());
    ui->barDownFile->setValue(0);

    if(!dwnFile->open(QIODevice::WriteOnly))
    {   //如果打开文件失败，则删除file，并使file指针为0，然后返回
        QMessageBox::warning(this,tr("下载错误"),tr("无法创建文件"));
        delete dwnFile;
        dwnFile =NULL;
        return;
    }
    QString downLoadFileUrl=buildDownFileUrl(ConsumerKey,ConsumerSecret,\
                                             mAuTokenInfo.auToken,mAuTokenInfo.auTokenSecret,\
                                             isAppPath,fromPath);
    inputUrl.setEncodedUrl(downLoadFileUrl.toAscii());
    request.setUrl(inputUrl);
    mDownloadFileReply=manager->get(request);
    connect(mDownloadFileReply,SIGNAL(finished()),this,SLOT(downLoadFileReplyFinished()));
}

//构造 下载文件的url
QString kpDemo::buildDownFileUrl(QString &consKeyStr, QString &consKeySecretStr,\
                                 QString &oauTknStr, QString &oauTknSercetStr, \
                                 bool &isAppPath, QString &fromPath)
{
    QString para;
    QString _dwnFileUrl=DOWNLOAD_FILE_URL;
    _dwnFileUrl.append("?");
    _dwnFileUrl.append(OASIGNATURE);
    _dwnFileUrl.append(getDownFileSignature(para,consKeyStr,consKeySecretStr,\
                                           oauTknStr,oauTknSercetStr,isAppPath,fromPath));
    //添加签名
    _dwnFileUrl.append("&");
    _dwnFileUrl.append(para);//添加无编码的参数
    return _dwnFileUrl;
}

//构造 下载文件的签名
//oauth_consumer_key
//oauth_nonce
//oauth_timestamp
//oauth_token
//path
//root
QString kpDemo::getDownFileSignature(QString &paraStr, QString &consKeyStr, QString &consKeySecretStr,\
                                     QString &oauTknStr, QString &oauTknSercetStr, \
                                     bool &isAppPath, QString &fromPath)
{
    QString dwnFileBaseUrl;
    dwnFileBaseUrl.clear(); //将请求的URI路径进行URL编码
    dwnFileBaseUrl.append("GET&");
    dwnFileBaseUrl.append(QUrl::toPercentEncoding(DOWNLOAD_FILE_URL));
    dwnFileBaseUrl.append("&");

    paraStr.append(DATA_FROM_PATH);
    paraStr.append(QUrl::toPercentEncoding(fromPath));
    paraStr.append("&");

    //对参数进行升序排列 然后合并
    addTknNonceTimes(paraStr,consKeyStr);
    paraStr.append("&");
    paraStr.append(OATOKEN);        //oauth_token
    paraStr.append(oauTknStr);

    paraStr.append("&");
    paraStr.append(FOLDER_NAME);
    paraStr.append(QUrl::toPercentEncoding(fromPath));
    paraStr.append("&");
    paraStr.append(FOLDER_ROOT);
    if(isAppPath)
    {
        paraStr.append("app_folder");
    }
    else
    {
        paraStr.append("kuaipan");
    }

    dwnFileBaseUrl.append(QUrl::toPercentEncoding(paraStr));// 对参数进行编码 然后合并成源串
    QString secret=consKeySecretStr.append("&");//构建密钥
    secret=secret.append(oauTknSercetStr);
    return  hmacSha1(secret.toAscii(),dwnFileBaseUrl.toAscii()); //返回签名
}

//反馈完毕 获取重定向地址
void kpDemo::downLoadFileReplyFinished()
{
    QVariant returnCode = mDownloadFileReply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    if(301==returnCode.toInt() ||  302==returnCode.toInt())
    {
        for(int i=0;i<mDownloadFileReply->rawHeaderPairs().count();i++)
        {
            //qDebug()<<"Pairs()"<<mDownloadFileReply->rawHeaderPairs().at(i) ;
            if(mDownloadFileReply->rawHeaderPairs().at(i).first == "Location")
            {
                QUrl realDwnFileUrl=QUrl(mDownloadFileReply->rawHeaderPairs().at(i).second);
                mDwnFileRealReply=manager->get(QNetworkRequest(realDwnFileUrl));//用重定向地址重新下载
                connect(mDwnFileRealReply,SIGNAL(readyRead()),this,SLOT(dwnFileRealReadReady()));
                connect(mDwnFileRealReply,SIGNAL(finished()),this,SLOT(dwnFileRealReplyFinished()));
                connect(mDwnFileRealReply,SIGNAL(downloadProgress(qint64,qint64)),\
                        this,SLOT(showDownProgress(qint64,qint64)));
                break;
            }
        }
    }
    mDownloadFileReply->deleteLater();
}

//重定向后 获得下载文件反馈
void kpDemo::dwnFileRealReadReady()
{
    int ret=mDwnFileRealReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    if(CORRECT_RESULT==ret)//返回正确
    {
        if (dwnFile!=NULL) dwnFile->write(mDwnFileRealReply->readAll());
    }
    else
    {
        qDebug("error!!");
        QByteArray errorInfo("下载出错");
        showErrInfo(ret,errorInfo);
    }
}

//重定向后 下载文件完毕
void kpDemo::dwnFileRealReplyFinished()
{
    QMessageBox::information(this,"通知","下载完成！");
    mDwnFileRealReply->deleteLater();
    dwnFile->flush();
    dwnFile->close();
    delete dwnFile;
    dwnFile=NULL;
}

//显示下载进度
void kpDemo::showDownProgress(qint64 bytesRead, qint64 totalBytes)
{
    ui->barDownFile->setMaximum(totalBytes);
    ui->barDownFile->setValue(bytesRead);
}

//--------------------------------------分享文件
//请求分享文件
void kpDemo::reqShareFile()
{
    bool isAppPath=true;
    QString ConsumerKey=QString(CONSUMER_KEY);
    QString ConsumerSecret=QString(CONSUMER_SECRET);
    QString sharePath=QUrl::toPercentEncoding(ui->tFileNeedToShare->text());
    QString shareFileUrl=buildShareFileUrl(ConsumerKey,ConsumerSecret,\
                                           mAuTokenInfo.auToken,mAuTokenInfo.auTokenSecret,\
                                           isAppPath,sharePath);
    ui->tShareUrl->clear();
    qDebug()<<shareFileUrl;
    inputUrl.setEncodedUrl(shareFileUrl.toAscii());
    request.setUrl(inputUrl);
    mShareFileReply=manager->get(request);
    connect(mShareFileReply,SIGNAL(readyRead()),this,SLOT(shareFileReadReady()));
    connect(mShareFileReply,SIGNAL(finished()),this,SLOT(shareFileReplyFinished()));
}

//构造分享文件 url
QString kpDemo::buildShareFileUrl(QString &consKeyStr, QString &consKeySecretStr,\
                                  QString &oauTknStr, QString &oauTknSercetStr,\
                                  bool &isAppPath, QString &dataPath)
{
    QString para;
    QString newShareFileUrl(SHARE_FILE_URL);
    if(isAppPath)
    {
        newShareFileUrl.append("app_folder");
    }
    else newShareFileUrl.append("kuaipan");
    if(dataPath.length()>0)
    {
        newShareFileUrl.append("/");
        newShareFileUrl.append(dataPath);
    }

    QString _shareFileUrl=newShareFileUrl;
    _shareFileUrl.append("?");
    _shareFileUrl.append(OASIGNATURE);
    _shareFileUrl.append(getShareFileSignature(para,consKeyStr,consKeySecretStr,\
                                               oauTknStr,oauTknSercetStr,\
                                               newShareFileUrl));
    //添加签名
    _shareFileUrl.append("&");
    _shareFileUrl.append(para);//添加无编码的参数
    return _shareFileUrl;
}

//构造 分享文件 签名
//oauth_consumer_key
//oauth_nonce
//oauth_timestamp
//oauth_token
QString kpDemo::getShareFileSignature(QString &paraStr, QString &consKeyStr, QString &consKeySecretStr,\
                                      QString &oauTknStr, QString &oauTknSercetStr,\
                                      QString &newShareFileUrl)
{
    QString shareFileBaseUrl;
    shareFileBaseUrl.clear(); //将请求的URI路径进行URL编码
    shareFileBaseUrl.append("GET&");
    shareFileBaseUrl.append(QUrl::toPercentEncoding(newShareFileUrl));
    shareFileBaseUrl.append("&");

    //对参数进行升序排列 然后合并
    addTknNonceTimes(paraStr,consKeyStr);
    paraStr.append("&");
    paraStr.append(OATOKEN);        //oauth_token
    paraStr.append(oauTknStr);

    shareFileBaseUrl.append(QUrl::toPercentEncoding(paraStr));// 对参数进行编码 然后合并成源串
    QString secret=consKeySecretStr.append("&");//构建密钥
    secret=secret.append(oauTknSercetStr);
    return  hmacSha1(secret.toAscii(),shareFileBaseUrl.toAscii()); //返回签名
}

//分享文件 收到反馈
void kpDemo::shareFileReadReady()
{
    int ret=mShareFileReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QByteArray getBuf=mShareFileReply->readAll();
    if(CORRECT_RESULT==ret)//返回正确
    {
        procShareFile(getBuf);
    }
    else
    {
        showErrInfo(ret,getBuf);
    }
}

//分享文件 反馈完毕
void kpDemo::shareFileReplyFinished()
{
    mShareFileReply->deleteLater();
}

//提取分享文件 反馈信息
void kpDemo::procShareFile(const QByteArray &buf)
{
    QList<QByteArray> list=buf.split('"');
    ui->tShareUrl->setText(QString(list.at(3)));
}

//---------------------------------------以上为快盘api相关， 以下为界面操作----------------------------------
//打开要上传的文件
void kpDemo::openUploadFile()
{
    QString fileName = QFileDialog::getOpenFileName(this,tr("选择要上传的文件")\
                                                    ,tr(""),tr("支持类型(*.*)"));
    if(fileName.isEmpty())
    {
        return;
    }
    else
    {
        QFile file(fileName);
        if(!file.open(QIODevice::ReadOnly))
        {
            QMessageBox::information(this,tr("Unable to open file"),file.errorString());
            return;
        }
        else
        {//将文件路径显示出来
            ui->tLocalUploadPath->setText(file.fileName());
            ui->tRemoteUploadPath->setText(fileName.section('/',-1));
            //ui->lineEdit->setText(fileName.section('/',-1));
        }
    }
}

//选择保存下载文件路径
void kpDemo::saveDwnloadFile()
{
    QString fileName = QFileDialog::getSaveFileName(this,tr("选择保存位置")\
                                                    ,tr(""),tr("(*.*)"));
    if(fileName.isEmpty())
    {
        return;
    }
    else
    {
        QFile file(fileName);
        //将文件路径显示出来
        ui->tLocalDwnPath->setText(file.fileName());
        //ui->lineEdit->setText(fileName.section('/',-1));
    }
}



















